
package com.damai.utils.value;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.citywithincity.db.DBException;
import com.citywithincity.db.interfaces.IValueConvert;
import com.citywithincity.utils.ClassUtil;
import com.citywithincity.utils.IoUtil;

/**
 * 值转化器
 * 
 * @author renxueliang
 *
 */
public class ValueConvertFactory {

	private static Map<Class<?>, IValueConvert> map = new ConcurrentHashMap<Class<?>, IValueConvert>();

	static class Blob2byteArray implements IValueConvert {

		@Override
		public Object convert(Object value) {
			if (value instanceof Blob) {
				Blob blob = (Blob) value;
				BufferedInputStream reader = null;
				try {
					reader = new BufferedInputStream(blob.getBinaryStream());
					byte[] buffer = new byte[1024];
					ByteArrayOutputStream out = new ByteArrayOutputStream();
					int len = 0;
					while ((len = reader.read(buffer, 0, 1024)) > 0) {
						out.write(buffer, 0, len);
					}
					return out.toByteArray();
				} catch (SQLException e) {
					throw new DBException(e);
				} catch (IOException e) {
					throw new DBException(e);
				} finally {
					IoUtil.close(reader);
				}
			} else {
				return value;
			}

		}

	}

	static class BigDecimal2boolean implements IValueConvert {
		BigDecimal2boolean() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return false;
			return ((BigDecimal) value).intValue() > 0;
		}

	}

	static class String2double implements IValueConvert {
		String2double() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return (double) 0;
			return Double.parseDouble((String) value);
		}

	}

	static class BigDecimal2double implements IValueConvert {
		BigDecimal2double() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return (double) 0;
			return ((BigDecimal) value).doubleValue();
		}

	}

	static class BigDecimal2int implements IValueConvert {
		BigDecimal2int() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return 0;
			return ((BigDecimal) value).intValue();
		}

	}

	static class BigDecimal2long implements IValueConvert {
		BigDecimal2long() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return (long) 0;
			return ((BigDecimal) value).longValue();
		}

	}

	static class Blob2byte implements IValueConvert {
		Blob2byte() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return value;
			Blob blob = (Blob) value;
			InputStream inputStream = null;
			try {
				byte[] bytes = new byte[(int) blob.length()];
				inputStream = blob.getBinaryStream();
				inputStream.read(bytes);
				return bytes;
			} catch (SQLException e) {
				throw new DBException(e);
			} catch (IOException e) {
				throw new DBException(e);
			} finally {
				IoUtil.close(inputStream);
			}

		}

	}

	static class Double2int implements IValueConvert {
		Double2int() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return (int) 0;
			return (int) (double) (Double) value;
		}

	}

	static class Integer2boolean implements IValueConvert {
		Integer2boolean() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return 0;
			return ((Integer) value) > 0;
		}

	}

	static class Integer2long implements IValueConvert {
		Integer2long() {

		}

		@Override
		public Object convert(Object value) {
			return (long) (int) (Integer) value;
		}

	}

	static class Long2int implements IValueConvert {
		Long2int() {

		}

		@Override
		public Object convert(Object value) {
			return (int) (long) (Long) value;
		}

	}

	static class Long2long implements IValueConvert {
		Long2long() {

		}

		@Override
		public Object convert(Object value) {

			return value;
		}

	}

	static class String2int implements IValueConvert {
		String2int() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return 0;
			return Integer.parseInt((String) value);
		}

	}

	static class String2long implements IValueConvert {
		String2long() {

		}

		@Override
		public Object convert(Object value) {
			if (value == null)
				return (long) 0;
			return Long.parseLong((String) value);
		}

	}

	private static IValueConvert create(String name) throws Exception {
		Class<?> clazz = Class.forName(name);
		IValueConvert valueConvert = map.get(clazz);
		if (valueConvert == null) {
			valueConvert = (IValueConvert) clazz.newInstance();
			map.put(clazz, valueConvert);
		}
		return valueConvert;
	}

	public static IValueConvert create(Class<?> fromClass, Class<?> toClass) throws Exception {
		if(ClassUtil.isEqual(fromClass, toClass)){
			return null;
		}
		return create(fromClass.getSimpleName(), toClass.getSimpleName());
	}
	
	public static IValueConvert create(String fromClass,String toClass) throws Exception{
		char c = toClass.charAt(0);
		String start = "";
		if (c >= 'a' && c <= 'z') {
			start = "ValueConvertFactory$";
		}
		return create(new StringBuilder(30).append("com.damai.utils.value.")
				.append(start)
				.append(fromClass.replace("[]", "Array")).append("2")
				.append(toClass.replace("[]", "Array")).toString());
	}

}
